#include "driverlib.h"
#include "msp430.h"
#include <stdint.h>
#include <intrinsics.h>
//问题解决了，参考了I2CDev中的库
// 软件定时相关操作
#define F_CPU ((double)1200000)
#define delay_us(x) __delay_cycles((long)(F_CPU*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(F_CPU*(double)x/1000.0))

#define TX_STATE 0
#define RX_STATE 1

static uint8_t TxByteCnt = 0;
static uint8_t RxByteCnt = 0;
static uint8_t * pTxData;
static uint8_t * pRxData;

uint8_t I2C_State = 0;

#define SLAVE_ADDRESS 0x50

void i2c_clear_error() {
	P3SEL &= ~BIT1;                        // P3.1@UCB0SCL

	P3DIR |= BIT1;
	P3OUT |= BIT1;

	uint8_t i;
	// 输出9个时钟以恢复I2C总线状态
	for (i = 0; i < 9; i++) {
		P3OUT |= BIT1;
		__delay_cycles(8000);
		P3OUT &= ~BIT1;
		__delay_cycles(8000);
	}
}

void I2C_Init() {
	//Assign I2C pins to USCI_B0
	GPIO_setAsPeripheralModuleFunctionInputPin(
	GPIO_PORT_P3,
	GPIO_PIN0 + GPIO_PIN1);

	//Initialize Master
	USCI_B_I2C_initMasterParam param = { 0 };
	param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK;
	param.i2cClk = UCS_getSMCLK();
	param.dataRate = USCI_B_I2C_SET_DATA_RATE_400KBPS;
	USCI_B_I2C_initMaster(USCI_B0_BASE, &param);

	//Specify slave address
	USCI_B_I2C_setSlaveAddress(USCI_B0_BASE, SLAVE_ADDRESS);

	//Enable I2C Module to start operations
	USCI_B_I2C_enable(USCI_B0_BASE);
}

void I2C_Tx_Init() {
	__disable_interrupt();
	USCI_B_I2C_setMode(USCI_B0_BASE, USCI_B_I2C_TRANSMIT_MODE);
	//Enable master Receive interrupt
	USCI_B_I2C_clearInterrupt(USCI_B0_BASE, USCI_B_I2C_TRANSMIT_INTERRUPT);
	USCI_B_I2C_enableInterrupt(USCI_B0_BASE, USCI_B_I2C_TRANSMIT_INTERRUPT);
	//I2C_State = TX_STATE;
	__enable_interrupt();
}

void I2C_Rx_Init() {
	__disable_interrupt();
	USCI_B_I2C_setMode(USCI_B0_BASE, USCI_B_I2C_TRANSMIT_MODE);
	//Enable master Receive interrupt
	USCI_B_I2C_clearInterrupt(USCI_B0_BASE, USCI_B_I2C_RECEIVE_INTERRUPT);
	USCI_B_I2C_enableInterrupt(USCI_B0_BASE, USCI_B_I2C_RECEIVE_INTERRUPT);
	//I2C_State = RX_STATE;
	__enable_interrupt();
}

uint8_t I2C_TxFrame(uint8_t * p_Tx, uint8_t num) {

	if ((UCB0STAT & UCBUSY) || (UCB0CTL1 & UCTXSTP))
		return (1);

	pTxData = (uint8_t *) p_Tx;
	TxByteCnt = num;
	UCB0CTL1 |= UCTR + UCTXSTT;

	//UCB0TXBUF = *pTxData;
	//pTxData++;
	//TxByteCnt--;

	//__bis_SR_register(LPM0 + GIE);

	return 0;
}

uint8_t I2C_RxFrame(uint8_t * p_Rx, uint8_t num) {

	if ((UCB0STAT & UCBUSY) || (UCB0CTL1 & UCTXSTP))
		return (1);

	pRxData = (uint8_t *) p_Rx;
	RxByteCnt = num;
	//关键在这里要分两种情况进行处理
	if (num == 1) {
		USCI_B_I2C_masterReceiveSingleStart(USCI_B0_BASE);
	} else {
		USCI_B_I2C_masterReceiveMultiByteStart(USCI_B0_BASE);
	}

	//__bis_SR_register(LPM0 + GIE);

	return 0;
}

uint8_t addressdata[] = { 0x00, 0x00 };
uint8_t readdata[] = { 0x00, 0x00 };

void main(void) {

	WDT_A_hold(WDT_A_BASE);
	i2c_clear_error();
	I2C_Init();
	I2C_State = RX_STATE;

	while (1) {
		I2C_Tx_Init();
		I2C_TxFrame(addressdata, 2);
		I2C_Rx_Init();
		I2C_RxFrame(readdata, 2);
		__delay_cycles(80000);
	}
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B0_VECTOR)))
#endif
void USCI_B0_ISR(void) {
	switch (__even_in_range(UCB0IV, 12)) {
	case USCI_I2C_UCRXIFG: {
		RxByteCnt--;
		if (RxByteCnt) {
			if (RxByteCnt == 1) {
				UCB0CTL1 |= UCTXSTP;
				*pRxData = UCB0RXBUF;
			} else
				*pRxData++ = UCB0RXBUF;
		} else {
			*pRxData++ = UCB0RXBUF;
		}
		break;
	}
	case USCI_I2C_UCTXIFG:

		if (TxByteCnt) {
			UCB0TXBUF = *pTxData;
			pTxData++;
			TxByteCnt--;
		} else {
			UCB0CTL1 |= UCTXSTP;
			UCB0IFG &= ~UCTXIFG;
		}

		break;

	default:
		break;
	}
}
